package com.lagou.edu.factory;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.net.URL;
import java.util.List;

public class ApplicationContext extends AbstructBeanFactory {


    private static boolean annotationConfigue = false;

    static{
        // 任务一：读取解析xml，通过反射技术实例化对象并且存储待用（map集合）
        // 加载xml
        InputStream resourceAsStream = ApplicationContext.class.getClassLoader().getResourceAsStream("beans.xml");
        // 解析xml
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();
            //获取所有的bean
            List<Element> beanList = rootElement.selectNodes("//bean");
            //扫描是否开启注解配置
            List<Element> componentScan = rootElement.selectNodes("//component-scan");
            if (componentScan != null) {
                if ( componentScan.size() == 1 ){
                    annotationConfigue = true;
                } else {
                    throw new RuntimeException("component-scan 只能有1个");
                }
            }

            // 如果开启了注解扫描，则扫描目录创建bean
            if (annotationConfigue) {
                String packageName = componentScan.get(0).attributeValue("base-package");
                initAnnotationContext(packageName, true);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化环境
     * @param packageName 包名
     * @param isRecursion 是否遍历子包
     * @return 类的完整名称
     */
    public static void initAnnotationContext(String packageName, boolean isRecursion) throws Exception {
        // 初始化proxy
        doCreateBean(getBeanDefinition(ProxyFactory.class.getCanonicalName()));
        // 加载并解析xml配置文件
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        String packagePath = packageName.replace(".", "/");
        URL url = loader.getResource(packagePath);
        if (url != null) {
            String protocol = url.getProtocol();
            if (protocol.equals("file")) {
                try {
                    // 创建bean
                    createBean(url.getPath(), packageName, isRecursion);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else {
                throw new RuntimeException("扫描路径并不是文件夹：" + packageName);
            }
        } else {
            throw new RuntimeException("扫描包路径不存在：" + packageName);
        }
    }
}
